package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.nursing.dto.DeviceDto;
import com.zzyl.nursing.vo.DeviceDetailVo;
import com.zzyl.nursing.vo.DeviceReportDataVo;
import com.zzyl.nursing.vo.ProductVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceMapper;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.nursing.domain.Product;
import com.zzyl.nursing.mapper.ProductMapper;

/**
 * 设备Service业务层处理
 *
 * @author Zhy
 * @date 2025-03-06
 */
@Service
@RequiredArgsConstructor
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {

	private final DeviceMapper deviceMapper;
	private final RedisTemplate<String, String> redisTemplate;
	private final ProductMapper productMapper;

	/**
	 * 查询设备列表
	 *
	 * @param device 设备
	 * @return 设备
	 */
	@Override
	public List<Device> selectDeviceList(Device device) {
		return deviceMapper.selectDeviceList(device);
	}

	/**
	 * 从物联网平台同步产品列表
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public void syncProductList() {
		// 移除 IOT 平台同步产品列表的逻辑
	}

	/**
	 * 查询所有产品列表
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public List<ProductVo> allProduct() {
		List<Product> products = productMapper.selectAll();
		List<ProductVo> vos = new ArrayList<>();
		for (Product p : products) {
			ProductVo vo = new ProductVo();
			vo.setProductId(String.valueOf(p.getId()));
			vo.setProductKey(p.getProductKey());
			vo.setProductName(p.getProductName());
			vos.add(vo);
		}
		return vos;
	}

	/**
	 * 注册设备
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public void registerProduct(DeviceDto deviceDto) {
		// 1. 检查设备名字是否重复
		LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
		long count = count(queryWrapper.eq(Device::getDeviceName, deviceDto.getDeviceName()));
		if (count > 0) {
			throw new BaseException("设备名字重复");
		}

		// 2. 检查设备标识是否重复
		queryWrapper = new LambdaQueryWrapper<>();
		count = count(queryWrapper.eq(Device::getNodeId, deviceDto.getNodeId()));
		if (count > 0) {
			throw new BaseException("设备标识重复");
		}

		// 3. 检查同一个位置是否绑定的相同的产品
		queryWrapper = new LambdaQueryWrapper<>();
		count = count(queryWrapper.eq(Device::getBindingLocation, deviceDto.getBindingLocation())
			.eq(Device::getProductKey, deviceDto.getProductKey())
			.eq(Device::getLocationType, deviceDto.getLocationType()));
		if (count > 0) {
			throw new BaseException("同一个位置不能绑定同类型的产品");
		}

		// 补全实体
		String secret = UUID.randomUUID().toString().replace("-", "");
		String iotId = UUID.randomUUID().toString().replace("-", "");

		// 4. 注册设备到 IOT 平台
		// 封装发送的请求
		// 移除 IOT 平台注册设备的逻辑

		// 5. 保存设备信息到数据库
		Device device = BeanUtil.toBean(deviceDto, Device.class);
		device.setSecret(secret);
		device.setIotId(iotId);
		try {
			save(device);
		} catch (Exception e) {
			// 删除 IOT 平台注册的设备
			// TODO

			throw new BaseException("新增设备信息失败，请联系管理员");
		}
	}

	/**
	 * 查询设备详细数据
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public DeviceDetailVo queryDeviceDetail(String iotId) {
		// 1. 查询数据库中是否有数据
		LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
		Device device = getOne(queryWrapper.eq(Device::getIotId, iotId));
		if (ObjUtil.isEmpty(device)) {
			return null;
		}

		// 2. 查询 IOT
		// 移除 IOT 平台查询设备详情的逻辑

		// 3. 整合属性
		DeviceDetailVo deviceDetailVo = BeanUtil.toBean(device, DeviceDetailVo.class);
		// 移除 IOT 平台获取设备状态的逻辑
		deviceDetailVo.setDeviceStatus("OFFLINE"); // 默认离线
		String activeTimeStr = null; // 移除 IOT 平台获取激活时间的逻辑
		if (ObjUtil.isNotEmpty(activeTimeStr)) {
			LocalDateTime activeTime = LocalDateTimeUtil.parse(activeTimeStr, DatePattern.UTC_MS_PATTERN);
			// 日期时区转换
			activeTime = activeTime.atZone(ZoneId.from(ZoneOffset.UTC))
				.withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
				.toLocalDateTime();
			deviceDetailVo.setActiveTime(activeTime);
		}

		return deviceDetailVo;
	}

	/**
	 * 查询设备上报数据
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public List/*<DeviceReportDataVo>*/ queryDeviceReportData(String iotId) {
		// 移除 IOT 平台查询设备上报数据的逻辑，直接返回空集合
		return new ArrayList<>();
	}

	/**
	 * 更新设备数据
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public void updateDevice(Device device) {
		// 1. 更新 IOT
		// 移除 IOT 平台更新设备的逻辑

		// 2. 更新数据库
		try {
			updateById(device);
		} catch (Exception e) {
			// TODO
			// 回滚 IOT 更新

			throw new BaseException("数据库更新设备信息失败");
		}
	}

	/**
	 * 删除设备
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public void deleteDeviceByIotId(String iotId) {
		// 1. 删除 IOT 上的设备
		// 移除 IOT 平台删除设备的逻辑

		// 2. 删除数据库中的设备信息
		try {
			LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(Device::getIotId, iotId);
			remove(queryWrapper);
		} catch (Exception e) {
			throw new BaseException("数据库删除设备信息失败");
		}
	}

	/**
	 * 获取产品对应的服务信息
	 *
	 * @return:
	 * @param:
	 */
	@Override
	public List/*<ServiceCapability>*/ queryProductByProductKey(String productKey) {
		// 彻底移除 IOT 相关逻辑，直接返回空集合
		return Collections.emptyList();
	}

}
